#!/bin/bash

#Debian based apt-compare utily
#Author: Arunoda Susiripala
#Licence: http://www.gnu.org/licenses/gpl-3.0.txt
#Copyright: Arunoda Susiripala
#E-mail: me@arunoda.com


APT_CACHE='/var/cache/apt/archives'
PKG_OUT=$PKG_NAME #new package location
ARCHIVE_LOC='archives';

mkdir $ARCHIVE_LOC 2> /dev/null

function check_it {
	# follow is a hack to remove recursive checks to same thing
	for lc in  $(seq 1 1 $NEW_PKGS_CNT)
	do
		pac=`echo ${NEW_PKGS[$lc]}`
		if [ ! $pac == "" ]; then
			if [ $pac == $1 ]; then
				return
			fi
		fi
		
	done
	
	# checking whether $1 exists in PKG_LIST
	ans_go=`grep -E ^$1$ PKG_LIST | wc -w`
	if [  $ans_go -eq 0 ]; then
		#check for package available actually used in this OS 
		# (to remove optional packages)
		res=`dpkg -l | tail -n +6 | cut -d " " -f3 | grep ^$1$`
		if [ $res ]; then 
			echo "need 2 get: " $res
			NEW_PKGS[$NEW_PKGS_CNT]=`echo $1`
			NEW_PKGS_CNT=`expr $NEW_PKGS_CNT + 1`
			
			#getting dependencies for $1 (only one level)
			local TMP_PKGS=`apt-cache depends -i $1 | tail -n +2 | sed -s 's/.*: //'` 
			local CNT=`echo $TMP_PKGS | wc -w`
			
			#recursivly call for dependace packages to check unmet their dependancies
			for lc in  $(seq 1 1 $CNT)
			do
				
				local package=`echo $TMP_PKGS | cut -d" " -f$lc`
				check_it $package
				
			done
		fi		
	fi

}


function process_pkg {

	filename=`ls $APT_CACHE | grep $1'_'`
	echo $1 ... $filename

	if [ '$filename'  ]; then
		echo $filename
		#this is a hack to allow more files of one package..
		#now we are getting the lates package from the cache if multiple versions of the package exists...
		arr=$(echo $filename | tr " " "\n")
		local maxtime=0;
		local latest_package;
		for file in $arr
		do
			filetime=`stat -c %Y $APT_CACHE/$file`
			if [ $filetime > $maxtime ]; then
				latest_package=$file
			fi	
		done
		
		cp $APT_CACHE/$file $ARCHIVE_LOC
		echo $file >> "$PKG_NAME"_list
	else
		echo "   + " $1 | tee $PKG_OUT_NEED_DOWNLOAD
	fi
}

function main_process {
	# start point for getting packages
	echo 'cheking'
	check_it $PKG_NAME
	echo 'check-done'
	
	echo > "$PKG_NAME"_list
	for lc in $(seq 0 1 `expr $NEW_PKGS_CNT - 1`)
	do
		#echo ${NEW_PKGS[$lc]}
		process_pkg ${NEW_PKGS[$lc]}
	done
	
	echo
	echo " * Total $NEW_PKGS_CNT package(s) fetched from the apt cache"
	echo " * Following packages to be retrieved manually "
	echo "-------------------------------------------------------------"
	echo ""
	
	
	
}

function install {
	local pkg_list=""
		arr=$(echo ${@:2} | tr " " "\n")
		for package in $arr
		do
			if [ ! -e "$package"_list ]; then
				echo $package not exists on the archieve
				continue
			fi
			
			while read line
			do
				if [ $line ]; then
					pkg_list="$ARCHIVE_LOC/$line $pkg_list"	
				fi
			done < "$package"_list
		done
	
	dpkg -i $pkg_list
}


if [ ! $1 ]; then
	echo "apt-compare - compare packages between 2 debian based hosts" \
	 " and fetch packages from the cache and display packages you've to find manually" | fmt ;echo
	echo "USAGE:"
	echo " apt-compare -m [create package list(PKG_LIST) from the current OS to be compare with another OS]"
	echo " apt-compare <package-name> [compare and fetch packages]"
	echo "  assume that PKG_LIST(generated by above) is in the working directory"
elif [ $1 == "-m" ]; then
	##creating the package list in the target OS
	dpkg -l | tail -n +6 | cut -d " " -f3> PKG_LIST
elif [ $1 == "-i" ]; then
	install $@
else
	echo $@
	arr=$(echo $@ | tr " " "\n")	
	for package in $arr
	do
		NEW_PKGS="";
		NEW_PKGS_CNT=0;
		PKG_NAME=$package
		##first check whether the software is installed in the system
		res=`dpkg -l | tail -n +6 | grep ii | cut -d " " -f3 | grep ^$PKG_NAME$`
		if [ $res ]; then 
			main_process
		else
			echo "$PKG_NAME is not instaled in the current system";
			echo "do you wanna install it now..? [y|n]"
			read ans
			if [ $ans == 'y' ]; then
				sudo apt-get install $PKG_NAME 
			
				##first check whether the software is installed in the system
				res=`dpkg -l | tail -n +6 | grep ii | cut -d " " -f3 | grep ^$PKG_NAME$`
				if [ $res ]; then
					main_process
				else
					echo "package doesnot exists in the software channel" 
				fi
			else
				echo "aborted!"
			fi
		fi	
	done

	
fi
